<template>
  <div v-loading="loading" class="container">

    <el-card style="width: 100%;">

      <el-form ref="form" :inline="true" label-position="left" size="mini">

        <el-form-item label="负载:">
          <el-select
            v-model="queriesSelectCondition"
            style="min-width: 130px; width: 60%; margin-right: 10px"
            clearable
            filterable
            placeholder="请选择负载"
          >
            <el-option
              v-for="item in queriesSelects"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="数据集:">

          <el-select
            v-model="dataSelectCondition"
            style="min-width: 130px; width: 60%; margin-right: 10px"
            clearable
            filterable
            placeholder="请选择数据集"
          >
            <el-option
              v-for="item in dataSelects"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="算法:">
          <el-select
            v-model="queriesSelectCondition"
            style="width: 180px;"
            clearable
            filterable
            placeholder="请选择算法"
          >
            <el-option
              v-for="item in queriesSelects"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="parameterOptimization()">新建优化</el-button>
        </el-form-item>

      </el-form>

      <el-divider />

      <div style="margin-top: 20px;">
        <el-table :data="optimizeArametersHistoryData" border header-align="center" height="500">
          <el-table-column prop="start_at" label="优化开始时间" width="160px" align="center" />
          <el-table-column prop="end_at" label="优化结束时间" width="160px" align="center">
            <template slot-scope="scope">
              {{ scope.row.end_at || '' }}
            </template>
          </el-table-column>
          <el-table-column label="table_open_cache(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.table_open_cache_before }}</div>
                /
                <div style="color: red">{{ scope.row.table_open_cache_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="innodb_buffer_pool_size(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.innodb_buffer_pool_size_before }}</div>
                /
                <div style="color: red">{{ scope.row.innodb_buffer_pool_size_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="innodb_purge_threads(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.innodb_purge_threads_before }}</div>
                /
                <div style="color: red">{{ scope.row.innodb_purge_threads_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="innodb_read_io_threads(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.innodb_read_io_threads_before }}</div>
                /
                <div style="color: red">{{ scope.row.innodb_read_io_threads_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="innodb_write_io_threads(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.innodb_write_io_threads_before }}</div>
                /
                <div style="color: red">{{ scope.row.innodb_write_io_threads_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="qps(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.qps_before }}</div>
                /
                <div style="color: red">{{ scope.row.qps_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="tps(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.tps_before }}</div>
                /
                <div style="color: red">{{ scope.row.tps_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="latency(前/后)" align="center">
            <template slot-scope="scope">
              <div v-if="scope.row.optimize_state === 2">
                <div style="color: #999999">{{ scope.row.latency_before }}</div>
                /
                <div style="color: red">{{ scope.row.latency_after }}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column fixed="right" prop="optimize_state" label="优化状态" :formatter="optimizeStateFormatter" align="center" />
          <el-table-column fixed="right" prop="after" label="操作" align="center">
            <el-button type="primary" size="mini" @click="onSubmitOptimize">提交优化</el-button>
          </el-table-column>
        </el-table>
        <el-pagination
          class="pagination"
          background=""
          layout="prev, pager, next"
          :current-page="pageIndex"
          :page-size="pageSize"
          :total="totalItems"
          @current-change="curPageChange"
        />
      </div>

      <el-divider />

      <div style="width: 100%; display: flex; flex-direction: row; margin-top: 20px">
        <div class="chart_container" style="width: 100%">
          <div class="chart_title">吞吐量</div>
          <lineChart id="zoneIoThroughputChart" style="width:100%; height:160px" :chart-option="zoneIoThroughputOption" />
        </div>
      </div>

    </el-card>

  </div>
</template>

<script>

import moment from 'moment'
import { mysqlStatus, optimizeArametersHistory, startOptimizeArameters } from '../../api/api'
import { query_range } from '../../api/prometheus'
import lineChart from '../../components/echarts/vue-chart'

const timeSpace = 30000

export default {
  name: 'Design',
  components: { lineChart },
  data() {
    return {
      timer: undefined,
      loading: false,
      pageSize: 15,
      pageIndex: 1,
      totalItems: 0,
      dbSelecteds: [
        { label: '数据库实例1 | DNMind_testing | id:23i', value: '0' }
      ],
      queriesSelectCondition: undefined,
      dataSelectCondition: undefined,
      queriesSelects: [
        { label: '当前负载', value: '0' },
        { label: 'TPC-H', value: '1' },
        { label: 'TPC-C', value: '2' },
        { label: 'JOB', value: '3' }
      ],
      dataSelects: [
        { label: '当前数据集', value: '0' },
        { label: 'TPC-H', value: '1' },
        { label: 'TPC-C', value: '2' },
        { label: 'JOB', value: '3' }
      ],
      optimizeArametersHistoryData: [],
      zoneIoThroughputChart: undefined,
      zoneDelayChart: undefined,
      timeRange: ['', ''],
      zoneDelayOption: {
        title: { show: false },
        color: ['#00FFFF', '#409EFF'],
        legend: {
          icon: 'roundRect',
          show: true,
          data: ['预测表现', '实际表现']
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          top: 30,
          bottom: 20
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          nameTextStyle: {
            color: '#666666'
          },
          axisLabel: {
            show: true,
            showMinLabel: true,
            fontSize: 10
          },
          axisLine: {
            show: true,
            lineStyle: {
              width: 0.5,
              color: '#999999',
              shadowColor: '#fff',
              shadowBlur: 10
            }
          },
          axisTick: {
            show: true,
            inside: true,
            length: 5,
            lineStyle: {
              width: 0.5,
              color: '#999999',
              shadowColor: '#fff',
              shadowBlur: 10
            }
          },
          data: []
        },
        yAxis: {
          type: 'value',
          offset: 0,
          nameTextStyle: {
            color: '#666666'
          },
          axisLabel: {
            show: true,
            showMinLabel: true,
            fontSize: 10
          },
          axisLine: {
            show: false
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: '#e5e5e5',
              type: 'dotted'
            }
          },
          axisTick: {
            show: false
          }
        },
        series: [
          {
            lineStyle: {
              color: '#00FFFF',
              width: 2
            },
            name: '预测表现',
            data: [],
            type: 'line',
            smooth: true,
            showSymbol: false,
            hoverAnimation: true
          }, {
            lineStyle: {
              color: '#409EFF',
              width: 2
            },
            nameTextStyle: {
              color: 'red'
            },
            label: {
              color: 'auto'
            },
            name: '实际表现',
            data: [],
            type: 'line',
            smooth: true,
            showSymbol: false,
            hoverAnimation: true
          }

        ]
      },
      zoneIoThroughputOption: {
        title: { show: false },
        color: ['#00FFFF', '#409EFF'],
        legend: {
          icon: 'roundRect',
          show: true,
          data: ['预测表现', '实际表现']
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          }
        },
        grid: {
          top: 30,
          bottom: 20
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          nameTextStyle: {
            color: '#666666'
          },
          axisLabel: {
            show: true,
            showMinLabel: true,
            fontSize: 10
          },
          axisLine: {
            show: true,
            lineStyle: {
              width: 0.5,
              color: '#999999',
              shadowColor: '#fff',
              shadowBlur: 10
            }
          },
          axisTick: {
            show: true,
            inside: true,
            length: 5,
            lineStyle: {
              width: 0.5,
              color: '#999999',
              shadowColor: '#fff',
              shadowBlur: 10
            }
          },
          data: []
        },
        yAxis: {
          type: 'value',
          offset: 0,
          nameTextStyle: {
            color: '#666666'
          },
          axisLabel: {
            show: true,
            showMinLabel: true,
            fontSize: 10
          },
          axisLine: {
            show: false
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: '#e5e5e5',
              type: 'dotted'
            }
          },
          axisTick: {
            show: false
          }
        },
        series: [
          {
            lineStyle: {
              color: '#00FFFF',
              width: 2
            },
            name: '预测表现',
            data: [],
            type: 'line',
            smooth: true,
            showSymbol: false,
            hoverAnimation: true
          }, {
            lineStyle: {
              color: '#409EFF',
              width: 2
            },
            nameTextStyle: {
              color: 'red'
            },
            label: {
              color: 'auto'
            },
            name: '实际表现',
            data: [],
            type: 'line',
            smooth: true,
            showSymbol: false,
            hoverAnimation: true
          }

        ]
      }
    }
  },
  mounted() {
    this.timeRange = [moment().add(-1, 'h').format('x'), moment().format('x')]

    this.mysqlStatus()
    this.optimizeArametersHistory()
    const that = this
    this.timer = setInterval(function() {
      that.mysqlStatus()
      that.optimizeArametersHistory()
    }, timeSpace)
  },
  destroyed() {
    window.onresize = null
    clearInterval(this.timer)
  },
  methods: {
    optimizeStateFormatter(row, column) {
      let optimize_state = ''
      switch (row.optimize_state) {
        case 0:
        case 1:
          optimize_state = '优化中'
          break
        case 2:
          optimize_state = '优化成功'
          break
        default:
          optimize_state = '优化失败'
          break
      }

      return optimize_state
    },
    onSubmitOptimize() {
      this.$confirm('此操作将修改该实例运行参数, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$message({
          type: 'success',
          message: '修改成功!'
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消修改'
        })
      })
    },
    optimizeArametersHistory() {
      this.loading = true
      const that = this
      optimizeArametersHistory({ server_id: 1, limit: 20, page: this.pageIndex }).then((res) => {
        that.optimizeArametersHistoryData = res.data
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    async curPageChange(page) {
      this.pageIndex = page
      this.optimizeArametersHistory()
    },
    mysqlStatus() {
      const that = this

      this.queryRangeRequest(`rate(mysql_global_status_questions{instance="8.131.229.55:9104"}[30s]) or irate(mysql_global_status_questions{instance="8.131.229.55:9104"}[30s])`).then(res => {
        const serverStatusData = res
        that.zoneIoThroughputOption.xAxis.data = []
        that.zoneIoThroughputOption.series[1].data = []
        that.zoneIoThroughputOption.series[0].data = []
        for (let i = 0; i < serverStatusData.length; i++) {
          const serverStatus = serverStatusData[i]

          that.zoneIoThroughputOption.xAxis.data.push(moment(serverStatus[0]).format('HH:mm:ss'))

          const queries_persecond = parseInt(serverStatus[1])
          let queries_persecond_random = parseInt(serverStatus[1])

          if (queries_persecond === 0) {
            // 0
            queries_persecond_random = 0
          } else if (queries_persecond < 10) {
            // queries_persecond + [-5，5]
            queries_persecond_random = Math.max(1, queries_persecond + 5 - parseInt((Math.random() * 10)))
          } else if (queries_persecond < 200) {
            // queries_persecond + 【-10，20】
            queries_persecond_random = Math.max(1, queries_persecond + 20 - parseInt((Math.random() * 30)))
          } else if (queries_persecond < 1000) {
            // queries_persecond + 【-100，100】
            queries_persecond_random = Math.max(1, queries_persecond + 100 - parseInt((Math.random() * 200)))
          } else if (queries_persecond < 2000) {
            // queries_persecond + 【-200，200】
            queries_persecond_random = Math.max(1, queries_persecond + 200 - parseInt((Math.random() * 400)))
          } else if (queries_persecond < 5000) {
            // queries_persecond + 【-500，500】
            queries_persecond_random = Math.max(1, queries_persecond + 500 - parseInt((Math.random() * 1000)))
          } else {
            // queries_persecond + 【-1000，1000】
            queries_persecond_random = Math.max(1, queries_persecond + 1000 - parseInt((Math.random() * 2000)))
          }
          that.zoneIoThroughputOption.series[0].data.push(queries_persecond_random)
          that.zoneIoThroughputOption.series[1].data.push(queries_persecond)
        }
      })
    },
    queryRangeRequest(queryUrl) {
      return new Promise((resolve, reject) => {
        query_range({
          query: queryUrl,
          start: this.timeRange[0] ? this.timeRange[0] / 1000 : (new Date()).valueOf() / 1000 - 3600 * 24,
          end: this.timeRange[1] ? this.timeRange[1] / 1000 : (new Date()).valueOf() / 1000,
          step: 30
        }).then(res => {
          const data = res.data.data
          if (data && data.result && data.result.length > 0) {
            if (data.result[0].values.length > 0) {
              const values = data.result[0].values
              var results = []
              for (let i = 0; i < values.length; i++) {
                const value = values[i]
                results.push([value[0] * 1000, value[1]])
              }
              resolve(results)
            } else {
              resolve(undefined)
            }
          } else {
            resolve(undefined)
          }
        })
      })
    },

    parameterOptimization() {
      const loading = this.$loading({
        lock: true,
        text: '优化任务创建中，请等待.',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      startOptimizeArameters({ server_id: 1 }).then((res) => {
        loading.close()
        this.$message({
          type: 'success',
          message: '优化任务创建成功! '
        })
        this.optimizeArametersHistory()
      }).catch(() => {
        loading.close()
      })
    }
  }
}
</script>

<style lang="scss" scoped>
    .container {
        display: flex;
        flex-direction: column;
    }

    body .el-table th.gutter{
        display: table-cell!important;
    }

    .table_container {
        padding: 10px;
    }

    .table_btns_container {
        display: flex;
        flex-direction: row;
        align-content: space-around;
        height: 40px;
        line-height: 40px;
        margin: 0 auto 20px auto;
        width: 100%;
    }

    .table_btns_item_container {
        flex: 0 0 33.333%;
        display: flex;
        justify-content: center;
    }

    .chart_title {
        width: 100%;
        height: 30px;
        font-size: 16px;
        font-weight: bold;
        color: #666666;
        text-align: center;
        line-height: 30px;
    }

    .chart_container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }
</style>
